The software core of a computer system (e.g., a system with one or more central processing unit (CPUs)) is generally referred to as the kernel of the computer system. The kernel includes an interrupt handler to handle requests for resources provided by the computer system and a scheduler that determines the order of the execution of various processes within the resources of the computer system. Additionally, the computer system may include a kernel tracing framework for tracing events performed by processes in the kernel.
Conventionally, the kernel tracing framework provides a set of programs and application program interfaces (APIs) that may be used to present an overview of the performance of any part of the kernel. The kernel tracing framework is also used to debug or observe operations within the kernel.
Typically, multiple threads are executing simultaneously within the system. When the kernel tracing framework is activated a tracing event (i.e., stores data regarding tracing events) is recorded whenever one of the threads executing in the system encounters a trace point (i.e., a point in the execution path of the thread at which data about the state of the kernel, etc. is collected) during executing. The tracing framework typically uses a global buffer (i.e., shared resource used by all the CPUs and kernel subsystems within the computer system) to record the tracing event. Based on the requests from the various threads, tracing event data is recorded sequentially into the global buffer. Once the global buffer becomes full, the global buffer is marked as such, and a new global buffer is allocated from the computer system memory resources.
Conventionally, in order to protect the global buffer from multiple threads storing data (i.e., tracing events) simultaneously, each thread obtains a lock for the global buffer prior to using the global buffer. The lock allows only the thread that obtained the lock to store data in the global buffer. Once the tracing event data is recorded in the global buffer, the thread releases the lock, thereby allowing another thread to obtain the lock and record tracing event data in the global buffer.
The thread that obtains the lock typically prevents other threads from accessing the global buffer for the amount of time needed to record tracing event data. In some instances, allowing only one thread to update the global buffer with tracing event data causes accesses to the buffer to become serialized. In other words, a thread that wants to record an event may be blocked from using the global buffer until the lock protecting the global buffer is released.